﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
using seejee_Backendium.Data.Repositores;

namespace seejee_Backendium.WEB.Middleware
{


    public class DbTokenValidationMiddleware
    {
        private readonly RequestDelegate _next;

        public DbTokenValidationMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            // 跳过AllowAnonymous的接口
            var endpoint = context.GetEndpoint();
            if (endpoint?.Metadata?.GetMetadata<Microsoft.AspNetCore.Authorization.IAllowAnonymous>() != null)
            {
                await _next(context);
                return;
            }

            // 只校验带有Authorization头的请求
            var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
            if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("Bearer "))
            {
                var token = authHeader.Substring("Bearer ".Length).Trim();

                // 解析token获取用户名
                var handler = new JwtSecurityTokenHandler();
                try
                {
                    var jwtToken = handler.ReadJwtToken(token);
                    var cOperatorName = jwtToken.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Name)?.Value;

                    if (!string.IsNullOrEmpty(cOperatorName))
                    {
                        // 读取数据库token
                        var repo = context.RequestServices.GetRequiredService<OperatorRepository>();
                        var dbToken = repo.GetTokenByOperatorName(cOperatorName);

                        // 对比token
                        if (dbToken != token)
                        {
                            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                            await context.Response.WriteAsync("Token无效或已过期");
                            return;
                        }
                    }
                }
                catch
                {
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    await context.Response.WriteAsync("Token解析失败");
                    return;
                }
            }
            await _next(context);
        }
    }
}
